From 39fcc013ef252b0bf2eecd63433da6ef232910e5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 23 Nov 2005 12:11:05 +0100 Subject: [PATCH] Intel systems with more than 8 CPUs require that the APIC is configured in clustered mode with the apic=bigsmp kernel parameter. This patch does the APIC mode selection automatically without needing to manually specify the kernel paremeter. (KAF note: I see the patch is also present in Linux 2.6.14.2) Signed-off-by: Nitin Kamble Signed-off-by: Venkatesh Pallipadi Signed-off-by: Andrew Morton --- xen/arch/x86/acpi/boot.c | 3 ++- xen/arch/x86/genapic/bigsmp.c | 5 ++++- xen/arch/x86/genapic/probe.c | 21 +++++++++++++++++++- xen/arch/x86/mpparse.c | 9 +++++++++ xen/include/asm-x86/apicdef.h | 1 + xen/include/asm-x86/mach-generic/mach_apic.h | 2 ++ xen/include/asm-x86/mpspec.h | 1 + 7 files changed, 39 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/acpi/boot.c b/xen/arch/x86/acpi/boot.c index 2d5b82cda4..12ead9691c 100644 --- a/xen/arch/x86/acpi/boot.c +++ b/xen/arch/x86/acpi/boot.c @@ -602,7 +602,8 @@ acpi_process_madt(void) error = acpi_parse_madt_lapic_entries(); if (!error) { acpi_lapic = 1; - + generic_bigsmp_probe(); + /* * Parse MADT IO-APIC entries */ diff --git a/xen/arch/x86/genapic/bigsmp.c b/xen/arch/x86/genapic/bigsmp.c index 93c00b9208..61b594a409 100644 --- a/xen/arch/x86/genapic/bigsmp.c +++ b/xen/arch/x86/genapic/bigsmp.c @@ -45,7 +45,10 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { static __init int probe_bigsmp(void) { - dmi_check_system(bigsmp_dmi_table); + if (def_to_bigsmp) + dmi_bigsmp = 1; + else + dmi_check_system(bigsmp_dmi_table); return dmi_bigsmp; } diff --git a/xen/arch/x86/genapic/probe.c b/xen/arch/x86/genapic/probe.c index a3a94fe753..cddde7a459 100644 --- a/xen/arch/x86/genapic/probe.c +++ b/xen/arch/x86/genapic/probe.c @@ -29,6 +29,25 @@ struct genapic *apic_probe[] __initdata = { NULL, }; +static int cmdline_apic; + +void __init generic_bigsmp_probe(void) +{ + /* + * This routine is used to switch to bigsmp mode when + * - There is no apic= option specified by the user + * - generic_apic_probe() has choosen apic_default as the sub_arch + * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support + */ + + if (!cmdline_apic && genapic == &apic_default) + if (apic_bigsmp.probe()) { + genapic = &apic_bigsmp; + printk(KERN_INFO "Overriding APIC driver with %s\n", + genapic->name); + } +} + static void __init genapic_apic_force(char *str) { int i; @@ -41,7 +60,7 @@ custom_param("apic", genapic_apic_force); void __init generic_apic_probe(void) { int i; - int changed = (genapic != NULL); + int changed = cmdline_apic = (genapic != NULL); for (i = 0; !changed && apic_probe[i]; i++) { if (apic_probe[i]->probe()) { diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c index 268c9cdf71..91355de55e 100644 --- a/xen/arch/x86/mpparse.c +++ b/xen/arch/x86/mpparse.c @@ -63,6 +63,8 @@ int nr_ioapics; int pic_mode; unsigned long mp_lapic_addr; +unsigned int def_to_bigsmp; + /* Processor that is doing the boot up */ unsigned int boot_cpu_physical_apicid = -1U; unsigned int boot_cpu_logical_apicid = -1U; @@ -213,6 +215,13 @@ void __init MP_processor_info (struct mpc_config_processor *m) ver = 0x10; } apic_version[m->mpc_apicid] = ver; + if ((num_processors > 8) && + APIC_XAPIC(ver) && + (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) + def_to_bigsmp = 1; + else + def_to_bigsmp = 0; + bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; } diff --git a/xen/include/asm-x86/apicdef.h b/xen/include/asm-x86/apicdef.h index 5357707ced..93ae434496 100644 --- a/xen/include/asm-x86/apicdef.h +++ b/xen/include/asm-x86/apicdef.h @@ -16,6 +16,7 @@ #define GET_APIC_VERSION(x) ((x)&0xFF) #define GET_APIC_MAXLVT(x) (((x)>>16)&0xFF) #define APIC_INTEGRATED(x) ((x)&0xF0) +#define APIC_XAPIC(x) ((x) >= 0x14) #define APIC_TASKPRI 0x80 #define APIC_TPRI_MASK 0xFF #define APIC_ARBPRI 0x90 diff --git a/xen/include/asm-x86/mach-generic/mach_apic.h b/xen/include/asm-x86/mach-generic/mach_apic.h index b13767a4e9..d9dc039da9 100644 --- a/xen/include/asm-x86/mach-generic/mach_apic.h +++ b/xen/include/asm-x86/mach-generic/mach_apic.h @@ -28,4 +28,6 @@ #define enable_apic_mode (genapic->enable_apic_mode) #define phys_pkg_id (genapic->phys_pkg_id) +extern void generic_bigsmp_probe(void); + #endif /* __ASM_MACH_APIC_H */ diff --git a/xen/include/asm-x86/mpspec.h b/xen/include/asm-x86/mpspec.h index 7add527173..1e3d48a470 100644 --- a/xen/include/asm-x86/mpspec.h +++ b/xen/include/asm-x86/mpspec.h @@ -11,6 +11,7 @@ extern int mp_bus_id_to_local [MAX_MP_BUSSES]; extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; +extern unsigned int def_to_bigsmp; extern unsigned int boot_cpu_physical_apicid; extern int smp_found_config; extern void find_smp_config (void); -- 2.30.2